package com.sky.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Setmeal;
import com.sky.mapper.DishMapper;
import com.sky.result.Result;
import com.sky.service.*;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@RestController("userDishController")
@RequestMapping("/user")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {
    @Autowired
    private DishService dishService;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    SetmealService setmealService;
    @Autowired
    SetmealDishService setmealDishService;
    @Autowired
    DishFlavorService dishFlavorService;
    @Autowired
    RedisTemplate redisTemplate;

    // 缓存过期时间：60分钟
    private static final long  CACHE_EXPIRE_MINUTES = 60;

    /**
     * 查询分类（添加缓存）
     */
    @GetMapping("/category/list")
    @ApiOperation("查询分类")
    public Result<List<Category>> listCategory(@RequestParam(required = false) Integer type){
        // 构建缓存key，包含type参数
        String key = "category_list_" + (type != null ? type : "all");

        // 先从缓存获取
        List<Category> categoryList = (List<Category>) redisTemplate.opsForValue().get(key);
        if (categoryList != null && !categoryList.isEmpty()) {
            log.info("从缓存获取分类数据，key: {}", key);
            return Result.success(categoryList);
        }

        // 缓存未命中，查询数据库
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(type != null, Category::getType, type);
        categoryList = categoryService.list(queryWrapper);

        // 存入缓存并设置过期时间
        redisTemplate.opsForValue().set(key, categoryList, CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        log.info("分类数据存入缓存，key: {}", key);

        return Result.success(categoryList);
    }

    /**
     * 根据分类id查询菜品（优化缓存实现）
     */
    @GetMapping("/dish/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<DishVO>> listDishByCategoryId(@RequestParam("categoryId") Long categoryId) {
        // 构建缓存key
        String key = "dish_" + categoryId;

        // 先从缓存获取
        List<DishVO> dishVOList = (List<DishVO>) redisTemplate.opsForValue().get(key);
        if (dishVOList != null && !dishVOList.isEmpty()) {
            log.info("从缓存获取菜品数据，key: {}", key);
            return Result.success(dishVOList);
        }

        // 缓存未命中，查询数据库
        dishVOList = dishService.listDishByCategoryId(categoryId);

        // 存入缓存并设置过期时间
        redisTemplate.opsForValue().set(key, dishVOList, CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        log.info("菜品数据存入缓存，key: {}", key);

        return Result.success(dishVOList);
    }

    /**
     * 根据分类id查询套餐（修改URL路径和方法名）
     */
    @GetMapping("/setmeal/list")  // 唯一路径：/user/dish/setmeal/byCategoryId
    @ApiOperation("根据分类id查询套餐")
    //使用缓存注解来实现缓存
    @Cacheable(cacheNames = "setmealCache", key = "#categoryId") //key: setmealCache::categoryId
    public Result<List<SetmealVO>> listSetmealByCategoryId(@RequestParam("categoryId") Integer categoryId) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Setmeal::getCategoryId, categoryId);
        List<Setmeal> list = setmealService.list(queryWrapper);
        List<SetmealVO> setmealVOList = new ArrayList<>();
        for (Setmeal setmeal : list) {
            SetmealVO setmealVO = new SetmealVO();
            BeanUtils.copyProperties(setmeal, setmealVO);
            setmealVOList.add(setmealVO);
        }
        return Result.success(setmealVOList);
    }


    /**
     * 根据套餐id查询包含的菜品列表（添加缓存）
     */
    @GetMapping("/setmeal/{id}")
    @ApiOperation("根据套餐id查询包含的菜品列表")
    public Result<List<DishItemVO>> dishList(@PathVariable("id") Long id){
        // 构建缓存key
        String key = "setmeal_dishes_" + id;

        // 先从缓存获取
        List<DishItemVO> dishItemVOList = (List<DishItemVO>) redisTemplate.opsForValue().get(key);
        if (dishItemVOList != null && !dishItemVOList.isEmpty()) {
            log.info("从缓存获取套餐包含的菜品数据，key: {}", key);
            return Result.success(dishItemVOList);
        }

        // 缓存未命中，查询数据库
        dishItemVOList = dishMapper.dishList(id);

        // 存入缓存并设置过期时间
        redisTemplate.opsForValue().set(key, dishItemVOList, CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        log.info("套餐包含的菜品数据存入缓存，key: {}", key);

        return Result.success(dishItemVOList);
    }

}
